package com.billsystem.fisco;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.fisco.bcos.sdk.abi.FunctionReturnDecoder;
import org.fisco.bcos.sdk.abi.TypeReference;
import org.fisco.bcos.sdk.abi.datatypes.Event;
import org.fisco.bcos.sdk.abi.datatypes.Function;
import org.fisco.bcos.sdk.abi.datatypes.Type;
import org.fisco.bcos.sdk.abi.datatypes.Utf8String;
import org.fisco.bcos.sdk.abi.datatypes.generated.Int256;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple1;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple5;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple6;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.contract.Contract;
import org.fisco.bcos.sdk.crypto.CryptoSuite;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.eventsub.EventCallback;
import org.fisco.bcos.sdk.model.CryptoType;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.model.callback.TransactionCallback;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;

@SuppressWarnings("unchecked")
public class Record extends Contract {
    public static final String[] BINARY_ARRAY = {"60806040523480156200001157600080fd5b506110016000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166356004b6a6040805190810160405280600681526020017f7265636f726400000000000000000000000000000000000000000000000000008152506040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040162000101919062000270565b602060405180830381600087803b1580156200011c57600080fd5b505af115801562000131573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525062000157919081019062000174565b506200031a565b60006200016c8251620002c9565b905092915050565b6000602082840312156200018757600080fd5b600062000197848285016200015e565b91505092915050565b6000620001ad82620002be565b808452620001c3816020860160208601620002d3565b620001ce8162000309565b602085010191505092915050565b6000600882527f7265636f726469640000000000000000000000000000000000000000000000006020830152604082019050919050565b6000602f82527f757365724e616d652c7370656e642c636f6d6d656e742c6163636f756e744e6160208301527f6d652c696e636f6d65457870656e6400000000000000000000000000000000006040830152606082019050919050565b600060608201905081810360008301526200028c8184620001a0565b90508181036020830152620002a181620001dc565b90508181036040830152620002b68162000213565b905092915050565b600081519050919050565b6000819050919050565b60005b83811015620002f3578082015181840152602081019050620002d6565b8381111562000303576000848401525b50505050565b6000601f19601f8301169050919050565b611c2e806200032a6000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806311dd884514610051578063f06b3b7914610092575b600080fd5b34801561005d57600080fd5b5061007860048036036100739190810190611390565b6100cf565b60405161008995949392919061180c565b60405180910390f35b34801561009e57600080fd5b506100b960048036036100b49190810190611412565b610c2b565b6040516100c69190611754565b60405180910390f35b60608060608060606000806000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f23f63c96040805190810160405280600681526020017f7265636f726400000000000000000000000000000000000000000000000000008152506040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610188919061178a565b602060405180830381600087803b1580156101a257600080fd5b505af11580156101b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506101da919081019061133e565b93508373ffffffffffffffffffffffffffffffffffffffff16637857d7c96040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561024057600080fd5b505af1158015610254573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061027891908101906112c3565b92508273ffffffffffffffffffffffffffffffffffffffff1663cd30a1d18b6040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016102cf9190611882565b600060405180830381600087803b1580156102e957600080fd5b505af11580156102fd573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff1663e8434e398b856040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016103589291906117ac565b602060405180830381600087803b15801561037257600080fd5b505af1158015610386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506103aa91908101906112ec565b915060008273ffffffffffffffffffffffffffffffffffffffff1663949d225d6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561041257600080fd5b505af1158015610426573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061044a9190810190611367565b13151561048c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104839061190c565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663846719e060006040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016104e2919061176f565b602060405180830381600087803b1580156104fc57600080fd5b505af1158015610510573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506105349190810190611315565b90507f27ff38f52a1720967f391d77a7ccdda14a9b2cb61190627967e91b3e86e0a3fa8173ffffffffffffffffffffffffffffffffffffffff16639c981fcb6040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016105aa9061192c565b600060405180830381600087803b1580156105c457600080fd5b505af11580156105d8573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525061060191908101906113d1565b8273ffffffffffffffffffffffffffffffffffffffff16639c981fcb6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161065490611a2b565b600060405180830381600087803b15801561066e57600080fd5b505af1158015610682573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506106ab91908101906113d1565b8373ffffffffffffffffffffffffffffffffffffffff16639c981fcb6040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016106fe906119d6565b600060405180830381600087803b15801561071857600080fd5b505af115801561072c573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525061075591908101906113d1565b8473ffffffffffffffffffffffffffffffffffffffff16639c981fcb6040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016107a8906118b7565b600060405180830381600087803b1580156107c257600080fd5b505af11580156107d6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506107ff91908101906113d1565b8573ffffffffffffffffffffffffffffffffffffffff16639c981fcb6040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161085290611981565b600060405180830381600087803b15801561086c57600080fd5b505af1158015610880573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506108a991908101906113d1565b6040516108ba95949392919061180c565b60405180910390a18073ffffffffffffffffffffffffffffffffffffffff16639c981fcb6040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016109159061192c565b600060405180830381600087803b15801561092f57600080fd5b505af1158015610943573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525061096c91908101906113d1565b8173ffffffffffffffffffffffffffffffffffffffff16639c981fcb6040518163ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016109bf90611a2b565b600060405180830381600087803b1580156109d957600080fd5b505af11580156109ed573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610a1691908101906113d1565b8273ffffffffffffffffffffffffffffffffffffffff16639c981fcb6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610a69906119d6565b600060405180830381600087803b158015610a8357600080fd5b505af1158015610a97573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610ac091908101906113d1565b8373ffffffffffffffffffffffffffffffffffffffff16639c981fcb6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610b13906118b7565b600060405180830381600087803b158015610b2d57600080fd5b505af1158015610b41573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610b6a91908101906113d1565b8473ffffffffffffffffffffffffffffffffffffffff16639c981fcb6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610bbd90611981565b600060405180830381600087803b158015610bd757600080fd5b505af1158015610beb573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250610c1491908101906113d1565b985098509850985098505050505091939590929450565b6000806000806000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f23f63c96040805190810160405280600681526020017f7265636f726400000000000000000000000000000000000000000000000000008152506040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610cdc","919061178a565b602060405180830381600087803b158015610cf657600080fd5b505af1158015610d0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d2e919081019061133e565b92508273ffffffffffffffffffffffffffffffffffffffff166313db93466040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015610d9457600080fd5b505af1158015610da8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610dcc9190810190611315565b91508173ffffffffffffffffffffffffffffffffffffffff1663e942b5168b6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610e239190611882565b600060405180830381600087803b158015610e3d57600080fd5b505af1158015610e51573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663e942b5168a6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610eaa919061194c565b600060405180830381600087803b158015610ec457600080fd5b505af1158015610ed8573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663e942b516896040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610f319190611a4b565b600060405180830381600087803b158015610f4b57600080fd5b505af1158015610f5f573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663e942b516886040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401610fb891906119f6565b600060405180830381600087803b158015610fd257600080fd5b505af1158015610fe6573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663e942b516876040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161103f91906118d7565b600060405180830381600087803b15801561105957600080fd5b505af115801561106d573d6000803e3d6000fd5b505050508173ffffffffffffffffffffffffffffffffffffffff1663e942b516866040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016110c691906119a1565b600060405180830381600087803b1580156110e057600080fd5b505af11580156110f4573d6000803e3d6000fd5b505050508273ffffffffffffffffffffffffffffffffffffffff166331afac368b846040518363ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040161114f9291906117dc565b602060405180830381600087803b15801561116957600080fd5b505af115801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111a19190810190611367565b90508093505050509695505050505050565b60006111bf8251611b19565b905092915050565b60006111d38251611b2b565b905092915050565b60006111e78251611b3d565b905092915050565b60006111fb8251611b4f565b905092915050565b600061120f8251611b61565b905092915050565b600082601f830112151561122a57600080fd5b813561123d61123882611aad565b611a80565b9150808252602083016020830185838301111561125957600080fd5b611264838284611ba1565b50505092915050565b600082601f830112151561128057600080fd5b815161129361128e82611aad565b611a80565b915080825260208301602083018583830111156112af57600080fd5b6112ba838284611bb0565b50505092915050565b6000602082840312156112d557600080fd5b60006112e3848285016111b3565b91505092915050565b6000602082840312156112fe57600080fd5b600061130c848285016111c7565b91505092915050565b60006020828403121561132757600080fd5b6000611335848285016111db565b91505092915050565b60006020828403121561135057600080fd5b600061135e848285016111ef565b91505092915050565b60006020828403121561137957600080fd5b600061138784828501611203565b91505092915050565b6000602082840312156113a257600080fd5b600082013567ffffffffffffffff8111156113bc57600080fd5b6113c884828501611217565b91505092915050565b6000602082840312156113e357600080fd5b600082015167ffffffffffffffff8111156113fd57600080fd5b6114098482850161126d565b91505092915050565b60008060008060008060c0878903121561142b57600080fd5b600087013567ffffffffffffffff81111561144557600080fd5b61145189828a01611217565b965050602087013567ffffffffffffffff81111561146e57600080fd5b61147a89828a01611217565b955050604087013567ffffffffffffffff81111561149757600080fd5b6114a389828a01611217565b945050606087013567ffffffffffffffff8111156114c057600080fd5b6114cc89828a01611217565b935050608087013567ffffffffffffffff8111156114e957600080fd5b6114f589828a01611217565b92505060a087013567ffffffffffffffff81111561151257600080fd5b61151e89828a01611217565b9150509295509295509295565b61153481611b6b565b82525050565b61154381611b7d565b82525050565b61155281611b0f565b82525050565b61156181611b8f565b82525050565b600061157282611ae4565b808452611586816020860160208601611bb0565b61158f81611be3565b602085010191505092915050565b60006115a882611ad9565b8084526115bc816020860160208601611bb0565b6115c581611be3565b602085010191505092915050565b6000600882527f7265636f726469640000000000000000000000000000000000000000000000006020830152604082019050919050565b6000600b82527f6163636f756e744e616d650000000000000000000000000000000000000000006020830152604082019050919050565b6000601582527f5265636f726420646f6573206e6f7420657869737400000000000000000000006020830152604082019050919050565b6000600882527f757365724e616d650000000000000000000000000000000000000000000000006020830152604082019050919050565b6000600c82527f696e636f6d65457870656e6400000000000000000000000000000000000000006020830152604082019050919050565b6000600782527f636f6d6d656e74000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000600582527f7370656e640000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006020820190506117696000830184611549565b92915050565b60006020820190506117846000830184611558565b92915050565b600060208201905081810360008301526117a4818461159d565b905092915050565b600060408201905081810360008301526117c68185611567565b90506117d5602083018461152b565b9392505050565b600060408201905081810360008301526117f68185611567565b9050611805602083018461153a565b9392505050565b600060a08201905081810360008301526118268188611567565b9050818103602083015261183a8187611567565b9050818103604083015261184e8186611567565b905081810360608301526118628185611567565b905081810360808301526118768184611567565b90509695505050505050565b6000604082019050818103600083015261189b816115d3565b905081810360208301526118af8184611567565b905092915050565b600060208201905081810360008301526118d08161160a565b9050919050565b600060408201905081810360008301526118f08161160a565b905081810360208301526119048184611567565b905092915050565b6000602082019050818103600083015261192581611641565b9050919050565b6000602082019050818103600083015261194581611678565b9050919050565b6000604082019050818103600083015261196581611678565b905081810360208301526119798184611567565b905092915050565b6000602082019050818103600083015261199a816116af565b9050919050565b600060408201905081810360008301526119ba816116af565b905081810360208301526119ce8184611567565b905092915050565b600060208201905081810360008301526119ef816116e6565b9050919050565b60006040820190508181036000830152611a0f816116e6565b90508181036020830152611a238184611567565b905092915050565b60006020820190508181036000830152611a448161171d565b9050919050565b60006040820190508181036000830152611a648161171d565b90508181036020830152611a788184611567565b905092915050565b6000604051905081810181811067ffffffffffffffff82111715611aa357600080fd5b8060405250919050565b600067ffffffffffffffff821115611ac457600080fd5b601f19601f8301169050602081019050919050565b600081519050919050565b600081519050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000611b2482611aef565b9050919050565b6000611b3682611aef565b9050919050565b6000611b4882611aef565b9050919050565b6000611b5a82611aef565b9050919050565b6000819050919050565b6000611b7682611aef565b9050919050565b6000611b8882611aef565b9050919050565b6000611b9a82611b0f565b9050919050565b82818337600083830152505050565b60005b83811015611bce578082015181840152602081019050611bb3565b83811115611bdd576000848401525b50505050565b6000601f19601f83011690509190505600a265627a7a72305820d576d3d6b972bf0dc4341c2362ab7f173e20e22ea53163123efcb566a75375df6c6578706572696d656e74616cf50037"};

    public static final String BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", BINARY_ARRAY);

    public static final String[] SM_BINARY_ARRAY = {};

    public static final String SM_BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", SM_BINARY_ARRAY);

    public static final String[] ABI_ARRAY = {"[{\"constant\":false,\"inputs\":[{\"name\":\"recordid\",\"type\":\"string\"}],\"name\":\"getRecord\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"},{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"recordid\",\"type\":\"string\"},{\"name\":\"userName\",\"type\":\"string\"},{\"name\":\"spend\",\"type\":\"string\"},{\"name\":\"comment\",\"type\":\"string\"},{\"name\":\"accountName\",\"type\":\"string\"},{\"name\":\"incomeExpend\",\"type\":\"string\"}],\"name\":\"addRecord\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"count\",\"type\":\"int256\"}],\"name\":\"AddRecordResult\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"userName\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"spend\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"comment\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"accountName\",\"type\":\"string\"},{\"indexed\":false,\"name\":\"incomeExpend\",\"type\":\"string\"}],\"name\":\"GetRecordResult\",\"type\":\"event\"}]"};

    public static final String ABI = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", ABI_ARRAY);

    public static final String FUNC_GETRECORD = "getRecord";

    public static final String FUNC_ADDRECORD = "addRecord";

    public static final Event ADDRECORDRESULT_EVENT = new Event("AddRecordResult", 
            Arrays.<TypeReference<?>>asList(new TypeReference<Int256>() {}));
    ;

    public static final Event GETRECORDRESULT_EVENT = new Event("GetRecordResult", 
            Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
    ;

    protected Record(String contractAddress, Client client, CryptoKeyPair credential) {
        super(getBinary(client.getCryptoSuite()), contractAddress, client, credential);
    }

    public static String getBinary(CryptoSuite cryptoSuite) {
        return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY);
    }

    public TransactionReceipt getRecord(String recordid) {
        final Function function = new Function(
                FUNC_GETRECORD, 
                Arrays.<Type>asList(new Utf8String(recordid)),
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public byte[] getRecord(String recordid, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_GETRECORD, 
                Arrays.<Type>asList(new Utf8String(recordid)),
                Collections.<TypeReference<?>>emptyList());
        return asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForGetRecord(String recordid) {
        final Function function = new Function(
                FUNC_GETRECORD, 
                Arrays.<Type>asList(new Utf8String(recordid)),
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple1<String> getGetRecordInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_GETRECORD, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple1<String>(

                (String) results.get(0).getValue()
                );
    }

    public Tuple5<String, String, String, String, String> getGetRecordOutput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getOutput();
        final Function function = new Function(FUNC_GETRECORD, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple5<String, String, String, String, String>(

                (String) results.get(0).getValue(), 
                (String) results.get(1).getValue(), 
                (String) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (String) results.get(4).getValue()
                );
    }

    public TransactionReceipt addRecord(String recordid, String userName, String spend, String comment, String accountName, String incomeExpend) {
        final Function function = new Function(
                FUNC_ADDRECORD, 
                Arrays.<Type>asList(new Utf8String(recordid),
                new Utf8String(userName),
                new Utf8String(spend),
                new Utf8String(comment),
                new Utf8String(accountName),
                new Utf8String(incomeExpend)),
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public byte[] addRecord(String recordid, String userName, String spend, String comment, String accountName, String incomeExpend, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_ADDRECORD, 
                Arrays.<Type>asList(new Utf8String(recordid),
                new Utf8String(userName),
                new Utf8String(spend),
                new Utf8String(comment),
                new Utf8String(accountName),
                new Utf8String(incomeExpend)),
                Collections.<TypeReference<?>>emptyList());
        return asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForAddRecord(String recordid, String userName, String spend, String comment, String accountName, String incomeExpend) {
        final Function function = new Function(
                FUNC_ADDRECORD, 
                Arrays.<Type>asList(new Utf8String(recordid),
                new Utf8String(userName),
                new Utf8String(spend),
                new Utf8String(comment),
                new Utf8String(accountName),
                new Utf8String(incomeExpend)),
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple6<String, String, String, String, String, String> getAddRecordInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_ADDRECORD, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Utf8String>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple6<String, String, String, String, String, String>(

                (String) results.get(0).getValue(), 
                (String) results.get(1).getValue(), 
                (String) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (String) results.get(4).getValue(), 
                (String) results.get(5).getValue()
                );
    }

    public Tuple1<BigInteger> getAddRecordOutput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getOutput();
        final Function function = new Function(FUNC_ADDRECORD, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Int256>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple1<BigInteger>(

                (BigInteger) results.get(0).getValue()
                );
    }

    public List<AddRecordResultEventResponse> getAddRecordResultEvents(TransactionReceipt transactionReceipt) {
        List<EventValuesWithLog> valueList = extractEventParametersWithLog(ADDRECORDRESULT_EVENT, transactionReceipt);
        ArrayList<AddRecordResultEventResponse> responses = new ArrayList<AddRecordResultEventResponse>(valueList.size());
        for (EventValuesWithLog eventValues : valueList) {
            AddRecordResultEventResponse typedResponse = new AddRecordResultEventResponse();
            typedResponse.log = eventValues.getLog();
            typedResponse.count = (BigInteger) eventValues.getNonIndexedValues().get(0).getValue();
            responses.add(typedResponse);
        }
        return responses;
    }

    public void subscribeAddRecordResultEvent(String fromBlock, String toBlock, List<String> otherTopics, EventCallback callback) {
        String topic0 = eventEncoder.encode(ADDRECORDRESULT_EVENT);
        subscribeEvent(ABI,BINARY,topic0,fromBlock,toBlock,otherTopics,callback);
    }

    public void subscribeAddRecordResultEvent(EventCallback callback) {
        String topic0 = eventEncoder.encode(ADDRECORDRESULT_EVENT);
        subscribeEvent(ABI,BINARY,topic0,callback);
    }

    public List<GetRecordResultEventResponse> getGetRecordResultEvents(TransactionReceipt transactionReceipt) {
        List<EventValuesWithLog> valueList = extractEventParametersWithLog(GETRECORDRESULT_EVENT, transactionReceipt);
        ArrayList<GetRecordResultEventResponse> responses = new ArrayList<GetRecordResultEventResponse>(valueList.size());
        for (EventValuesWithLog eventValues : valueList) {
            GetRecordResultEventResponse typedResponse = new GetRecordResultEventResponse();
            typedResponse.log = eventValues.getLog();
            typedResponse.userName = (String) eventValues.getNonIndexedValues().get(0).getValue();
            typedResponse.spend = (String) eventValues.getNonIndexedValues().get(1).getValue();
            typedResponse.comment = (String) eventValues.getNonIndexedValues().get(2).getValue();
            typedResponse.accountName = (String) eventValues.getNonIndexedValues().get(3).getValue();
            typedResponse.incomeExpend = (String) eventValues.getNonIndexedValues().get(4).getValue();
            responses.add(typedResponse);
        }
        return responses;
    }

    public void subscribeGetRecordResultEvent(String fromBlock, String toBlock, List<String> otherTopics, EventCallback callback) {
        String topic0 = eventEncoder.encode(GETRECORDRESULT_EVENT);
        subscribeEvent(ABI,BINARY,topic0,fromBlock,toBlock,otherTopics,callback);
    }

    public void subscribeGetRecordResultEvent(EventCallback callback) {
        String topic0 = eventEncoder.encode(GETRECORDRESULT_EVENT);
        subscribeEvent(ABI,BINARY,topic0,callback);
    }

    public static Record load(String contractAddress, Client client, CryptoKeyPair credential) {
        return new Record(contractAddress, client, credential);
    }

    public static Record deploy(Client client, CryptoKeyPair credential) throws ContractException {
        return deploy(Record.class, client, credential, getBinary(client.getCryptoSuite()), "");
    }

    public static class AddRecordResultEventResponse {
        public TransactionReceipt.Logs log;

        public BigInteger count;
    }

    public static class GetRecordResultEventResponse {
        public TransactionReceipt.Logs log;

        public String userName;

        public String spend;

        public String comment;

        public String accountName;

        public String incomeExpend;
    }
}
